package com.website.quartz.mgr;

import com.alibaba.fastjson.JSON;
import com.website.mybatis.entity.Quartz;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.Map;

/**
 *
 * <p>@author zhangshuw
 * <p>2018/7/27
 */
@Component
public class QuartzTimerMgr {

    private static final String QUARTZ_TIMER_GROUP = "timerGroup";

    private static Logger logger = LoggerFactory.getLogger(QuartzTimerMgr.class);

    @Autowired
    private Scheduler scheduler;
    /**
     * 注册作业到调度器
     * @param quartzTimerModel 作业model
     */
    @SuppressWarnings("rawtypes")
    public boolean registerJobToScheduler(Quartz quartzTimerModel){
        try {
            if(!scheduler.isShutdown()){
                JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP));
                if(jobDetail == null){
                    jobDetail = JobBuilder.newJob(getJobClazz(quartzTimerModel.getJobClass()))
                            .withIdentity(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP).build();
                    String para = quartzTimerModel.getPara();
                    JobDataMap jobDataMap = jobDetail.getJobDataMap();
                    if (StringUtils.isNotBlank(para)) {
                        Map<String,Object> param = JSON.parseObject(para);
                        jobDataMap.putAll(param);
                    }
                }
                TriggerKey key = TriggerKey.triggerKey(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP);
                Trigger trigger = scheduler.getTrigger(key);
                if(trigger == null){
                    trigger = TriggerBuilder.newTrigger().withIdentity(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP)
                            .withSchedule(CronScheduleBuilder.cronSchedule(quartzTimerModel.getCron())).build();
                    scheduler.scheduleJob(jobDetail, trigger);
                }
                scheduler.resumeTrigger(key);
                logger.info("Add schedlued and Run success--------" + quartzTimerModel.getJobName());
            }else{
                logger.warn("调度器已停止，无法添加新任务");
                return false;
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }
    /**
     * 移除作业 调度器删除前会停止任务
     * @param quartzTimerModel 作业model
     */
    public boolean removeJob(Quartz quartzTimerModel){
        try {
            JobKey key = JobKey.jobKey(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP);
            if (scheduler.getJobDetail(key) != null) {
                scheduler.deleteJob(key);
            }
            return true;
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 暂停作业
     * @param quartzTimerModel 作业model
     * @throws SchedulerException 调度异常
     */
    public void pauseJob(Quartz quartzTimerModel) throws SchedulerException {
        JobKey key = JobKey.jobKey(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP);
        if (scheduler.getJobDetail(key) != null) {
            scheduler.pauseJob(key);
        }
    }

    /**
     * 恢复作业 如果是内存存放作业，如果其中不存在该作业，可能会失败
     * @param quartzTimerModel 作业model
     * @throws SchedulerException 调度异常
     * @throws ClassNotFoundException 类不存在异常
     * @throws ParseException 解析异常
     */
    public void resumeJob(Quartz quartzTimerModel, boolean ignoreFlag) throws Exception {
        JobKey key = JobKey.jobKey(quartzTimerModel.getJobName(), QUARTZ_TIMER_GROUP);
        if (scheduler.getJobDetail(key) != null) {
            if(ignoreFlag){
                removeJob(quartzTimerModel);
                registerJobToScheduler(quartzTimerModel);
            }else{
                scheduler.resumeJob(key);
            }
        } else {
            registerJobToScheduler(quartzTimerModel);
        }
    }
    @SuppressWarnings("unchecked")
    private Class<Job> getJobClazz(String clazz) throws ClassNotFoundException {
        return (Class<Job>) Class.forName(clazz);
    }

}
